package com.yanqu.road.server.gameplayer.module.wingroom;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.dao.impl.wingroom.WingRoomDataDaoImpl;
import com.yanqu.road.dao.impl.wingroom.chakra.*;
import com.yanqu.road.entity.activity.daomu.config.DaoMuPlayerLevelConfig;
import com.yanqu.road.entity.config.badge.BadgeConfig;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.LogWingRoomChakraDraw;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.wingroom.UserFurnitureSample;
import com.yanqu.road.entity.wingroom.WingRoomFurniture;
import com.yanqu.road.entity.wingroom.WingRoomRegion;
import com.yanqu.road.entity.wingroom.chakra.WingRoomChakraFurnitureChangeItem;
import com.yanqu.road.entity.wingroom.chakra.WingRoomChakraPatronsAddItem;
import com.yanqu.road.entity.wingroom.chakra.config.WingRoomChakraAttributeConfig;
import com.yanqu.road.entity.wingroom.chakra.config.WingRoomChakraChartConfig;
import com.yanqu.road.entity.wingroom.chakra.config.WingRoomChakraConfig;
import com.yanqu.road.entity.wingroom.chakra.config.WingRoomChakraWindWaterConfig;
import com.yanqu.road.entity.wingroom.chakra.data.UserWingRoomChakra;
import com.yanqu.road.entity.wingroom.chakra.data.UserWingRoomChakraBeVisitRecord;
import com.yanqu.road.entity.wingroom.chakra.data.UserWingRoomChakraDetail;
import com.yanqu.road.entity.wingroom.chakra.data.UserWingRoomFurnitureRewardRecord;
import com.yanqu.road.entity.wingroom.chakra.enums.WingRoomInstallTypeEnum;
import com.yanqu.road.entity.wingroom.chakra.enums.WingRoomPositionTypeEnum;
import com.yanqu.road.entity.wingroom.config.WingRoomFurnitureConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.WeightHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.WingRoomChakraProto.WingRoomChakraProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.AttributeModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.config.BadgeConfigMgr;
import com.yanqu.road.server.manger.config.PatronsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.manger.wingroom.WingRoomChakraMgr;
import com.yanqu.road.server.manger.wingroom.WingRoomConfigMgr;
import com.yanqu.road.server.pb.WingRoomChakraPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.FixSizeLinkedList;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.UUIDHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.commons.beanutils.BeanUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class WingRoomChakraModule extends GeneralModule {

    RandomHelper randomHelper = new RandomHelper();

    //命盘主数据
    private UserWingRoomChakra userWingRoomChakra;

    //四象 K1:职业, K2:类型, K3:位置,  V:四象数据
    private Map<Integer, Map<Integer, Map<Integer, UserWingRoomChakraDetail>>> userWingRoomChakraDetailMap = new ConcurrentHashMap<>();

    //家具解锁/升级奖励领取记录 K：家具ID,K:家具等级，V:奖励
    private Map<Integer, Map<Integer, UserWingRoomFurnitureRewardRecord>> userFurnitureRewardRecord = new ConcurrentHashMap<>();

    //被拜访记录
    private FixSizeLinkedList<UserWingRoomChakraBeVisitRecord> userBeVisitRecordList = new FixSizeLinkedList<>(GameConfig.CHAKRAS_VISIT_RECORD);

    public WingRoomChakraModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        //主数据
        this.userWingRoomChakra = new WingRoomChakraDaoImpl().getUserWingRoomChakra(player.getUserId());
        //详情数据
        this.userWingRoomChakraDetailMap = new WingRoomChakraDetailDaoImpl().getUserWingRoomChakraDetailMap(player.getUserId());
        //家具解锁/升级奖励领取记录
        this.userFurnitureRewardRecord = new WingRoomFurnitureRewardRecordDaoImpl().getData(player.getUserId());
        //被拜访记录
        new WingRoomChakraBeVisitRecordDaoImpl().initData(player.getUserId(), this.userBeVisitRecordList);
        //排序一下
        this.userBeVisitRecordList.sort(Comparator.comparing(UserWingRoomChakraBeVisitRecord::getCreateTime));
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        //主数据
        if (this.userWingRoomChakra != null) {
            if (this.userWingRoomChakra.isInsertOption()) {
                new WingRoomChakraDaoImpl().add(this.userWingRoomChakra);
            } else if (this.userWingRoomChakra.isUpdateOption()) {
                new WingRoomChakraDaoImpl().update(this.userWingRoomChakra);
            }
        }
        //命盘详情数据
        WingRoomChakraDetailDaoImpl wingRoomChakraDetailDao = new WingRoomChakraDetailDaoImpl();
        for (Map<Integer, Map<Integer, UserWingRoomChakraDetail>> typeMap : this.userWingRoomChakraDetailMap.values()) {
            for (Map<Integer, UserWingRoomChakraDetail> positionMap : typeMap.values()) {
                for (UserWingRoomChakraDetail chakraDetail : positionMap.values()) {
                    if (chakraDetail.isInsertOption()) {
                        wingRoomChakraDetailDao.add(chakraDetail);
                    } else if (chakraDetail.isUpdateOption()) {
                        wingRoomChakraDetailDao.update(chakraDetail);
                    }
                }
            }
        }
        //家具解锁/升级经历领取记录
        WingRoomFurnitureRewardRecordDaoImpl furnitureRewardRecordDao = new WingRoomFurnitureRewardRecordDaoImpl();
        for (Map<Integer, UserWingRoomFurnitureRewardRecord> map : this.userFurnitureRewardRecord.values()) {
            for (UserWingRoomFurnitureRewardRecord record : map.values()) {
                if (record.isInsertOption()) {
                    furnitureRewardRecordDao.add(record);
                }
            }
        }
        //被拜访记录
        WingRoomChakraBeVisitRecordDaoImpl beVisitRecordDao = new WingRoomChakraBeVisitRecordDaoImpl();
        for (UserWingRoomChakraBeVisitRecord beVisitRecord : this.userBeVisitRecordList) {
            if (beVisitRecord.isInsertOption()) {
                beVisitRecordDao.add(beVisitRecord);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        //数据初始化
        initBaseData();
        if (this.userWingRoomChakra != null) {
            //重新计算厢房风水上限
            long windWaterLimit = this.countWindWaterLimit();
            this.userWingRoomChakra.setWindWaterLimit(windWaterLimit);
            //计算风水数据，并同步
            this.recountWindWaterData();
        }
    }

    @Override
    public void loginSendMsg() {
        //同步数据
        this.syncData();
    }

    /**
     * 判断系统是否解锁
     * @return
     */
    public boolean checkSystemOpen() {
        return SystemOpenMgr.systemOpen(player, eSystemId.Chakra.getValue());
    }

    /**
     * 同步数据
     */
    public void syncData() {
        if (this.userWingRoomChakra != null) {
            WingRoomChakraProto.WingRoomChakraSyncData.Builder msg = WingRoomChakraProto.WingRoomChakraSyncData.newBuilder();
            int bfFlag = (int) player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.WingRoomChakraWindWaterPropBfFlag);
            msg.setChakraData(WingRoomChakraPb.buildChakraData(this.userWingRoomChakra, this.userWingRoomChakraDetailMap, this.getDailyVisitUserNumMap(), bfFlag));
            player.sendPacket(ClientProtocol.U_CHAKRA_SYNC_DATA, msg);
        }
    }

    /**
     * 初始化系统基础数据
     */
    public void initBaseData() {
        if (SystemOpenMgr.systemOpen(player, eSystemId.WingRoom.getValue()) && this.userWingRoomChakra == null) {
            //计算风水风水值上限
            long windWaterLimit = this.countWindWaterLimit();
            //计算家具风水值
            long windWater = this.countBaseWindWaterNotLimit();
            //初始化数据
            UserWingRoomChakra userWingRoomChakra = new UserWingRoomChakra();
            userWingRoomChakra.setUserId(player.getUserId());
            userWingRoomChakra.setWindWater(windWater);
            userWingRoomChakra.setWindWaterLimit(windWaterLimit);
            userWingRoomChakra.setChakraLevel(1);
            userWingRoomChakra.setChakraExp(0L);
            userWingRoomChakra.setDrawNum(0);
            userWingRoomChakra.setCreateTime(System.currentTimeMillis());
            userWingRoomChakra.setInsertOption();
            this.userWingRoomChakra = userWingRoomChakra;
            //计算风水等级
            int windWaterLevel = this.countWindWaterLevel();
            this.userWingRoomChakra.setWindWaterLevel(windWaterLevel);
            //排行更新
            this.changeWindWaterRank();
            //同步数据
            this.syncData();
        }
    }

    /**
     * 初始化命盘系统
     */
    public void initSystem() {
        //赠送5风水符
        Property property = new Property();
        property.setGood(GameConfig.CHAKRAS_WIND_WATER_PROP_ID, BigInteger.valueOf(GameConfig.CHAKRAS_NEWPLAYER_GUIDE_BESTOW));
        player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.WingRoomChakra, eLogMoneyType.WingRoomChakraSystemOpenReward);
    }

    /**
     * 重新计算风上上限，风水等级，风水值
     */
    public void reCountData() {
        //计算风水风水值上限
        long windWaterLimit = this.countWindWaterLimit();
        //计算家具风水值
        long windWater = this.countBaseWindWaterNotLimit();
        this.userWingRoomChakra.setWindWaterLimit(windWaterLimit);
        this.userWingRoomChakra.setWindWater(windWater);
        //根据风水值，获取等级
        int windWaterLevel = this.countWindWaterLevel();
        this.userWingRoomChakra.setWindWaterLevel(windWaterLevel);
        //排行变更
        this.changeWindWaterRank();
        //同步数据
        this.syncData();
    }

    /**
     * 获取命盘数据
     * @return
     */
    public UserWingRoomChakra getUserWingRoomChakra() {
        return userWingRoomChakra;
    }

    /**
     * 获取命盘详情数据
     * @return
     */
    public Map<Integer, Map<Integer, Map<Integer, UserWingRoomChakraDetail>>> getUserWingRoomChakraDetailMap() {
        return userWingRoomChakraDetailMap;
    }

    /**
     * 获取基础风水值（有上限，无加成）
     * @return
     */
    public long getRealWindWater() {
        return this.userWingRoomChakra.getRealWindWater();
    }

    /**
     * 获取总风水值（有上限，有加成）
     * @return
     */
    private long getTotalWindWater() {
        long windWater = this.userWingRoomChakra.getRealWindWater();
        //获取风水增加比例
        int windWaterAddRate = WingRoomChakraMgr.getVisitWindWaterAddRate(player.getUserId());
        BigDecimal rate = BigDecimal.valueOf(windWaterAddRate).divide(BigDecimal.valueOf(1000));
        BigDecimal addWindWater = BigDecimal.valueOf(windWater).multiply(rate);
        return windWater + addWindWater.setScale(0, RoundingMode.UP).longValue();
    }

    /**
     * 添加被拜访记录
     * @param visitUserId
     * @param visitUserBaseInfo
     */
    public synchronized void addBeVisitRecord(long visitUserId, UserBaseInfo visitUserBaseInfo) {
        UserWingRoomChakraBeVisitRecord record = new UserWingRoomChakraBeVisitRecord();
        record.setUserId(player.getUserId());
        record.setVisitUserId(visitUserId);
        record.setVisitUserInfo(visitUserBaseInfo);
        record.setCreateTime(System.currentTimeMillis());
        record.setInsertOption();
        this.userBeVisitRecordList.add(record);
        //获取风水增加比例
        int rate = WingRoomChakraMgr.getVisitWindWaterAddRate(player.getUserId());
        //榜单刷新
        this.changeWindWaterRank();
        //推送被拜访
        WingRoomChakraProto.WingRoomChakraBeVisitSyncData.Builder syncData = WingRoomChakraProto.WingRoomChakraBeVisitSyncData.newBuilder();
        syncData.setVisitPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(visitUserBaseInfo));
        syncData.setVisitAddRate(rate);
        player.sendPacket(Protocol.U_CHAKRA_SYNC_BE_VISIT, syncData);
    }

    /**
     * 计算风水等级上限
     * @return
     */
    public long countWindWaterLimit() {
        //基础风水值上限
        long baseLimit = GameConfig.CHAKRAS_INITIAL_GEOMANCY_MAXIMUMS;
        //家具提升的风水等级上限
        Map<Integer, UserFurnitureSample> furnitureSampleMap = player.getModule(WingRoomModule.class).getFurnitureMap();//玩家家具
        for (UserFurnitureSample userFurnitureSample : furnitureSampleMap.values()) {
            WingRoomFurnitureConfig furnitureConfig = WingRoomConfigMgr.getFurnitureConfig(userFurnitureSample.getFurnitureId());
            //多少级加多少次
//            for (int i = 0; i < userFurnitureSample.getLv(); i++) {
                baseLimit += (long) furnitureConfig.getIncreaseGeomancy() * userFurnitureSample.getLv();
//            }
        }
        return baseLimit;
    }

    /**
     * 增加风水上限
     * @param furnitureId
     */
    public void addWindWaterLimit(int furnitureId) {
        WingRoomFurnitureConfig furnitureConfig = WingRoomConfigMgr.getFurnitureConfig(furnitureId);
        long windWaterLimit = furnitureConfig.getIncreaseGeomancy();
        if (windWaterLimit > 0) {
            long newWindWaterLimit = this.userWingRoomChakra.getWindWaterLimit() + windWaterLimit;
            this.userWingRoomChakra.setWindWaterLimit(newWindWaterLimit);
            //重新计算风水值
            this.recountWindWaterData();
        }
    }

    /**
     * 计算基础风水值，无上限
     * @return
     */
    public long countBaseWindWaterNotLimit() {
        long baseWindWater = 0;
        //区域map
        Map<Integer, WingRoomRegion> regionMap = player.getModule(WingRoomModule.class).getWingRoomData().getRegionMap();
        for (WingRoomRegion region : regionMap.values()) {
            for (WingRoomFurniture furniture : region.getFurnitureList()) {
                WingRoomFurnitureConfig furnitureConfig = WingRoomConfigMgr.getFurnitureConfig(furniture.getFurnitureId());
                baseWindWater += furnitureConfig.getGeomancy();
            }
        }
        return baseWindWater;
    }

    /**
     * 计算风水等级
     * @return
     */
    public int countWindWaterLevel() {
        long windWater = this.getRealWindWater();
        List<WingRoomChakraWindWaterConfig> configList = WingRoomConfigMgr.getWingRoomChakraWindWaterConfigList();
        int level = 1;
        for (WingRoomChakraWindWaterConfig config : configList) {
            long geomancyId = config.getGeomancyId();
            if (windWater >= geomancyId) {
                level = config.getId();
            } else {
                break;
            }
            //达到最大等级，返回
            if (level >= configList.size()) {
                break;
            }
        }
        return level;
    }

    /**
     * 家具升级/解锁，奖励发放
     * @param furnitureId 家具ID
     * @param level 家具等级
     * @return Property
     */
    public Property upgradeFurnitureRewardGet(int furnitureId, int level) {
        Property property = new Property();
        //判断是否已经领取过
        if (this.checkFurnitureRewardIsGot(furnitureId, level)) {
            return property;
        }
        Map<Integer, String> rewardMap = WingRoomConfigMgr.getFurnitureUpgradeRewardMap(furnitureId);
        if (!rewardMap.isEmpty()) {
            String rewardStr = rewardMap.get(level);
            if (rewardStr != null) {
                //记录奖励领取
                this.addFurnitureRewardRecord(furnitureId, level);
                //奖励领取
                property = PropertyHelper.parseStringToProperty(rewardStr);
                player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.WingRoomChakra, eLogMoneyType.WingRoomChakraFunUpgradeReward);
            }
        }
        return property;
    }

    /**
     * 补发原来就有的奖金解锁/升级奖励
     */
    public void bfOldWindWaterProp() {
        Property property = new Property();
        //遍历全部家具
        Map<Integer, UserFurnitureSample> furnitureSampleMap = player.getModule(WingRoomModule.class).getFurnitureMap();//玩家家具
        for (UserFurnitureSample furniture :furnitureSampleMap.values()) {
            //获取奖励配置，遍历奖励配置，发放奖励
            Map<Integer, String> rewardMap = WingRoomConfigMgr.getFurnitureUpgradeRewardMap(furniture.getFurnitureId());
            for (Map.Entry<Integer, String> entry : rewardMap.entrySet()) {
                int level = entry.getKey();
                String reward = entry.getValue();
                //判断奖励是否已经领取过
                if (furniture.getLv() >= level && !this.checkFurnitureRewardIsGot(furniture.getFurnitureId(), level)) {
                    Property furnitureProp = PropertyHelper.parseStringToProperty(reward);
                    property.addProperty(furnitureProp);
                    //记录奖励已领取
                    this.addFurnitureRewardRecord(furniture.getFurnitureId(), level);
                } else {
                    break;
                }
            }
        }
        //发送奖励
        player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.WingRoomChakra, eLogMoneyType.WingRoomChakraInitSystemOldFunRewardBf);
        //记录玩家补发
        player.getModule(AttributeModule.class).addAttribute(ePlayerAttrType.WingRoomChakraWindWaterPropBfFlag, 1L);
        //同步
        WingRoomChakraProto.WingRoomChakraSendBfOldFurnitureRewardRespMsg.Builder msg = WingRoomChakraProto.WingRoomChakraSendBfOldFurnitureRewardRespMsg.newBuilder();
        msg.setRet(0);
        msg.setReward(PropertyHelper.parsePropertyToString(property));
        player.sendPacket(ClientProtocol.U_CHAKRA_SYNC_BF_OLD_FUN_REWARD, msg);
    }

    /**
     * 判断家具解锁/升级奖励是否领取 。true：已经领取，false：未领取
     * @param furnitureId
     * @param level
     * @return
     */
    public boolean checkFurnitureRewardIsGot(int furnitureId, int level) {
        Map<Integer, UserWingRoomFurnitureRewardRecord> map = this.userFurnitureRewardRecord.get(furnitureId);
        if (map != null) {
            return map.containsKey(level);
        }
        return false;
    }

    /**
     * 添加解锁/升级家具奖励记录
     * @param furnitureId
     * @param level
     */
    public void addFurnitureRewardRecord(int furnitureId, int level) {
        Map<Integer, UserWingRoomFurnitureRewardRecord> map = this.userFurnitureRewardRecord.computeIfAbsent(furnitureId, k -> new HashMap<>());
        UserWingRoomFurnitureRewardRecord furnitureRewardRecord = new UserWingRoomFurnitureRewardRecord();
        furnitureRewardRecord.setUserId(player.getUserId());
        furnitureRewardRecord.setFurnitureId(furnitureId);
        furnitureRewardRecord.setLevel(level);
        furnitureRewardRecord.setCreateTime(System.currentTimeMillis());
        furnitureRewardRecord.setInsertOption();
        map.put(level, furnitureRewardRecord);
    }

    /**
     * 增加命盘经验
     * @param exp
     */
    public void addExp(long exp) {
        long oldExp = this.userWingRoomChakra.getChakraExp();
        long newExp = oldExp + exp;
        this.userWingRoomChakra.setChakraExp(newExp);
        //判断有没有升级
        Long needTotalExp = WingRoomConfigMgr.getChakraNextLevelNeedTotalExp(this.userWingRoomChakra.getChakraLevel());
        if (needTotalExp != null) {
            if (newExp >= needTotalExp) {
                //升级
                this.userWingRoomChakra.setChakraLevel(this.userWingRoomChakra.getChakraLevel() + 1);
            }
        }
    }

    /**
     * 重新计算风水数据
     */
    public void recountWindWaterData() {
        //计算基础风水值
        long windWater = this.countBaseWindWaterNotLimit();
        //存储风水数据 and 同步风水数据
        this.saveWindWaterData(windWater);
    }

    /**
     * 重新计算风水数据。（只计算变化家具，不需要全部循环计算）
     * @param changeList
     */
    public void recountWindWaterData(List<WingRoomChakraFurnitureChangeItem> changeList) {
        long allChangeValue = 0;
        for (WingRoomChakraFurnitureChangeItem changeItem : changeList) {
            //获取风水值
            WingRoomFurnitureConfig furnitureConfig = WingRoomConfigMgr.getFurnitureConfig(changeItem.getFurnitureId());
            long changeValue = furnitureConfig.getGeomancy();
            if (changeItem.isStatus()) {
                allChangeValue += changeValue;
            } else {
                allChangeValue -= changeValue;
            }
        }
        if (allChangeValue != 0) {
            //计算风水值
            long windWater = this.userWingRoomChakra.getWindWater() + allChangeValue;
            //存储风水数据 and 同步风水数据
            this.saveWindWaterData(windWater);
        }
        //做一下保护，累加计算的情况下，风水值小于0，进行重新计算风水值
        if (this.getUserWingRoomChakra().getWindWater() < 0) {
            this.recountWindWaterData();
        }
    }

    /**
     * 存储风水数据
     * @param windWater 基础风水值
     */
    private void saveWindWaterData(long windWater) {
        //存储
        this.userWingRoomChakra.setWindWater(windWater);
        this.userWingRoomChakra.setUpdateTime(System.currentTimeMillis());
        //计算风水等级
        int level = this.countWindWaterLevel();
        this.userWingRoomChakra.setWindWaterLevel(level);
        //风水排行变更
        this.changeWindWaterRank();
        //同步数据
        this.syncData();
    }

    /**
     * 增加拜访玩家次数
     * @param beVisitUserId 被拜访的玩家id
     */
    public void addDailyVisitUserNum(long beVisitUserId) {
        this.userWingRoomChakra.addDailyVisitData(beVisitUserId);
    }

    /**
     * 获取拜访玩家的次数
     * @param visitUserId 拜访的玩家id
     * @return int 次数
     */
    public int getDailyVisitUserNum(long visitUserId) {
        return this.getDailyVisitUserNumMap().getOrDefault(String.valueOf(visitUserId), 0);
    }

    /**
     * 获取拜访玩家的次数MAP
     * @return
     */
    public Map<String, Integer> getDailyVisitUserNumMap() {
        //判断【上次清除拜访的玩家次数时间】和【当前事件】是否是同一天，如果不是，清除
        boolean oneDayFlag = DateHelper.checkTimeOneDay(System.currentTimeMillis(), this.userWingRoomChakra.getLastClearVisitTime());
        if (!oneDayFlag) {
            //清除
            this.userWingRoomChakra.clearDailyVisitData();
            this.userWingRoomChakra.setLastClearVisitTime(System.currentTimeMillis());
        }
        return this.userWingRoomChakra.getDailyVisitData();
    }

    /**
     * 每日重置
     */
    public void resetOneDay() {
        //同步（里面就有隔天重置判断）
        this.syncData();
    }

    /**
     * 排行变动
     */
    public void changeWindWaterRank() {
        try {
            RankMgr.changeUserRank(eBigRankType.Normal.getValue(), player.getUserId(), BigInteger.valueOf(this.getTotalWindWater()), eRankType.WingRoomWindWaterValue.getValue(), "");
        } catch (Exception ex) {
            log.error(ex);
        }
    }

    /**
     * 获取门客加成的【资质】
     * @param patronsId
     * @return
     */
    public long getPatronsAddQualification(int patronsId) {
        return this.getPatronsAddValue(patronsId, WingRoomPositionTypeEnum.POSITION_TYPE_MG);
    }

    /**
     * 获取门客加成的【赚钱】
     * @param patronsId
     * @return
     */
    public long getPatronsAddAbility(int patronsId) {
        return this.getPatronsAddValue(patronsId, WingRoomPositionTypeEnum.POSITION_TYPE_SX);
    }

    /**
     * 获取门客加成值
     * @param patronsId 门客ID
     * @param positionTypeEnum 1：命格加成（资质），2：四象加成（赚钱千分比）
     * @return
     */
    private long getPatronsAddValue(int patronsId, WingRoomPositionTypeEnum positionTypeEnum) {
        //门客配置
        PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(patronsId);
        //增加的资质
        long addValue = 0;
        //遍历【命格】，获取门客加成的资质
        Map<Integer, Map<Integer, UserWingRoomChakraDetail>> typeMap = userWingRoomChakraDetailMap.get(patronsInfo.getOccupation());
        if (typeMap != null) {
            Map<Integer, UserWingRoomChakraDetail> positionMap = typeMap.get(positionTypeEnum.getType());
            for (UserWingRoomChakraDetail chakraDetail : positionMap.values()) {
                for (WingRoomChakraPatronsAddItem item : chakraDetail.getPatronsList()) {
                    if (item.getPatronsId() == patronsId) {
                        addValue += item.getAddValue();
                    }
                }
            }
        }
        return addValue;
    }

    /**
     * 卜卦检测
     * @param occupation
     * @return
     */
    private int checkDraw(int occupation, int drawNum) {
        //判断该序号的命盘是否解锁
        int needLevel = WingRoomChakraMgr.getChakraUnlockLevel(occupation);
        if (this.userWingRoomChakra.getChakraLevel() < needLevel) {
            return GameErrorCode.E_CHAKRA_NOT_UNLOCK;
        }

        //判断系统是否解锁,
        if (!this.checkSystemOpen()) {
            return GameErrorCode.E_CHAKRA_NOT_UNLOCK;
        }

        //结识门客是否达到
        int patronsNum = player.getModule(PatronsModule.class).getUserPatronsMap().size();
        int needPatronsNum = getDrawPatronsPools(occupation);
        if (patronsNum < needPatronsNum) {
            return GameErrorCode.E_CHAKRA_PATRONS_NUM_NOT_ENOUGH;
        }

        //判断抽取次数是否符合
        int maxDrawNum = this.getOnceMaxDrawNum();
        if (drawNum > maxDrawNum) {
            return GameErrorCode.E_CHAKRA_MUL_DRAW_LOCK;
        }
        return 0;
    }

    /**
     * 获取一次操作可最大抽取的次数
     * @return
     */
    private int getOnceMaxDrawNum() {
        int maxNum = 1;
        if (!StringUtils.isNullOrEmpty(GameConfig.CHAKRAS_MAGNIFICATION)) {
            String[] arr = GameConfig.CHAKRAS_MAGNIFICATION.split("\\|");
            for (String item : arr) {
                String[] itemArr = item.split(";");
                int userDrawNum = Integer.parseInt(itemArr[0]);
                int onceMaxDrawNum = Integer.parseInt(itemArr[1]);
                if (this.userWingRoomChakra.getDrawNum() >= userDrawNum) {
                    maxNum = onceMaxDrawNum;
                } else {
                    break;
                }
            }
        }
        return maxNum;
    }

    /**
     * 获取命盘需要的门客数
     * @param occupation
     * @return
     */
    private int getDrawPatronsPools(int occupation) {
        String[] arr = GameConfig.CHAKRAS_PATRONS_POOLS_NUMBER.split(";");
        return Integer.parseInt(arr[occupation - 1]);
    }

    /**
     * 获取位置
     * @return
     */
    private int getDrawPosition() {
        String positionWeight = GameConfig.CHAKRAS_WEIGHT;
        return RandomHelper.getRandomKeyByWeight(positionWeight, ";", ",");//盘位
    }

    /**
     * 获取类型（四象或者命格）
     * @param occupation
     * @param position
     * @return
     */
    private int getDrawType(int occupation, int position) {
        //获取类型（四象或者命格）
        WingRoomChakraConfig chakraConfig = WingRoomConfigMgr.getWingRoomChakraConfig(occupation, position);
        if (chakraConfig == null) {
            log.error("厢房命盘-WingRoomChakraConfig配置不存在：{}，{}", occupation, position);
            return WingRoomPositionTypeEnum.POSITION_TYPE_MG.getType();
        }
        return chakraConfig.getLittleType();//四象或者命格
    }

    /**
     * 获取五行类型
     * @param type
     * @return
     */
    private int getDrawWxType(int type) {
        String wxWeightStr = GameConfig.CHAKRAS_OUTER_WEIGHT;
        if (type == WingRoomPositionTypeEnum.POSITION_TYPE_SX.getType()) {
            wxWeightStr = GameConfig.CHAKRAS_INTERNAL_WEIGHT;
        }
        return RandomHelper.getRandomKeyByWeight(wxWeightStr, ";", ",");//五行类型
    }

    /**
     * 获取等级
     * @return
     */
    private int getDrawLevel() {
        WingRoomChakraChartConfig chakraChartConfig = WingRoomConfigMgr.getWingRoomChakraChartConfig(this.userWingRoomChakra.getChakraLevel());
        return RandomHelper.getRandomKeyByWeight(chakraChartConfig.getParam(), ";", ",");
    }

    /**
     * 获取品质
     * @return
     */
    private int getDrawQuality() {
        List<Integer> drawQualityWeight = WingRoomConfigMgr.getWingRoomChakraWindWaterConfigByTotalWindWater(this.getTotalWindWater()).getWeightList();
        return RandomHelper.getRandomIndexByWeight(drawQualityWeight) + 1;
    }

    /**
     * 获取命盘上的装备详情
     * @param occupation
     * @param type
     * @param position
     * @return
     */
    private UserWingRoomChakraDetail getChakraDetail(int occupation, int type, int position) {
        Map<Integer, Map<Integer, UserWingRoomChakraDetail>> typeMap = this.userWingRoomChakraDetailMap.get(occupation);
        if (typeMap != null) {
            Map<Integer, UserWingRoomChakraDetail> positionMap = typeMap.get(type);
            if (positionMap != null) {
                return positionMap.get(position);
            }
        }
        return null;
    }

    /**
     * 获取引导必中装备
     * @return
     */
    private UserWingRoomChakraDetail getGuideDrawResult(int occupation) {
        String config = GameConfig.CHAKRAS_NEWPLAYER_GUIDE_GACHA;
        if (StringUtils.isNullOrEmpty(config)) {
            return null;
        }
        String[] configStrArr = config.split("\\|");
        //判断是否抽取次数抽过 configStrArr 长度的次数。没超过才走必中（默认前2次必中）
        if (this.userWingRoomChakra.getDrawNum() >= configStrArr.length) {
            return null;
        }
        String configStr = configStrArr[this.userWingRoomChakra.getDrawNum()];
        String[] itemStrArr = configStr.split(",");
        UserWingRoomChakraDetail userWingRoomChakraDetail = new UserWingRoomChakraDetail();
        userWingRoomChakraDetail.setUserId(player.getUserId());
        userWingRoomChakraDetail.setOccupation(occupation);
        userWingRoomChakraDetail.setType(WingRoomPositionTypeEnum.POSITION_TYPE_MG.getType());
        userWingRoomChakraDetail.setPosition(Integer.parseInt(itemStrArr[2]));
        userWingRoomChakraDetail.setWxType(Integer.parseInt(itemStrArr[3]));
        userWingRoomChakraDetail.setLevel(Integer.parseInt(itemStrArr[0]));
        userWingRoomChakraDetail.setQuality(Integer.parseInt(itemStrArr[1]));
        //获取赚钱第一的门客
        List<UserPatrons> patronsList = player.getModule(PatronsModule.class).getUserPatronsList();
        patronsList.sort(Comparator.comparing(UserPatrons::getAbility).reversed());
        List<UserPatrons> patronsListResult = new ArrayList<>();
        for (int i = 0; i < Integer.parseInt(itemStrArr[4]); i++) {
            patronsListResult.add(patronsList.get(0));
        }
        WingRoomChakraAttributeConfig attributeConfig = WingRoomConfigMgr.getWingRoomChakraAttributeConfig(userWingRoomChakraDetail.getQuality(), userWingRoomChakraDetail.getLevel());
        List<WingRoomChakraPatronsAddItem> patronsAddList = this.buildWingRoomChakraPatronsAddItemList(patronsListResult, WingRoomPositionTypeEnum.POSITION_TYPE_MG.getType(), attributeConfig);
        userWingRoomChakraDetail.setPatronsList(patronsAddList);
        return userWingRoomChakraDetail;
    }

    /**
     * 增加抽取次数
     */
    private void addDrawNum() {
        this.userWingRoomChakra.setDrawNum(this.userWingRoomChakra.getDrawNum() + 1);
        this.userWingRoomChakra.setUpdateTime(System.currentTimeMillis());
        player.notifyListener(eGamePlayerEventType.WingRoomChakraDraw.getValue(), 1);
    }


    /*****************************************************CMD***********************************************************/

//    /**
//     * 卜卦
//     * @param reqMsg
//     * @return
//     */
//    public synchronized WingRoomChakraProto.WingRoomChakraDrawRespMsg.Builder draw(WingRoomChakraProto.WingRoomChakraDrawReqMsg reqMsg) {
//        WingRoomChakraProto.WingRoomChakraDrawRespMsg.Builder respMsg = WingRoomChakraProto.WingRoomChakraDrawRespMsg.newBuilder();
//        int occupation = reqMsg.getOccupation();
//
//        //检测
//        int ret = this.checkDraw(occupation);
//        if (ret > 0) {
//            respMsg.setRet(ret);
//            return respMsg;
//        }
//
//        //判断【四象，命格】是否还未装备,如果有直接返回
//        UserWingRoomChakraDetail waitChakraDetail = this.userWingRoomChakra.getWaitChakraDetail();
//        if (waitChakraDetail != null) {
//            //返回PB
//            respMsg.setRet(0);
//            respMsg.setChakraExp(this.userWingRoomChakra.getChakraExp());
//            respMsg.setChakraLevel(this.userWingRoomChakra.getChakraLevel());
//            respMsg.setChakraItem(WingRoomChakraPb.builderChakraItem(waitChakraDetail));
//            return respMsg;
//        }
//
//        //命盘等级配置
//        WingRoomChakraChartConfig chakraChartConfig = WingRoomConfigMgr.getWingRoomChakraChartConfig(this.userWingRoomChakra.getChakraLevel());
//
//        //消耗道具
//        Property cost = new Property();
//        cost.setGood(GameConfig.CHAKRAS_WIND_WATER_PROP_ID, BigInteger.valueOf(chakraChartConfig.getConsume()));
//        boolean costResult = player.getModule(CurrencyModule.class).removeCurrency(cost, eLogMoneyType.WingRoomChakra, eLogMoneyType.WingRoomChakraDrawCost);
//        if (!costResult) {
//            //触发现金礼包
//            player.notifyListener(eGamePlayerEventType.RechargeWingRoomChakra.getValue(), 0);
//            respMsg.setRet(GameErrorCode.E_CHAKRA_DRAW_PROP_NOT_ENOUGH);
//            return respMsg;
//        }
//
//        //获取引导必中。没有引导必中走正常抽取
//        UserWingRoomChakraDetail userWingRoomChakraDetail = this.getGuideDrawResult(occupation);
//        if (userWingRoomChakraDetail == null) {
//            //根据配置，随机出四象或者命格。随机出哪个盘位
//            int position = this.getDrawPosition();
//            //获取类型（四象或者命格）
//            int type = this.getDrawType(occupation, position);
//            //根据配置，随机出五行类型
//            int wxType = this.getDrawWxType(type);
//            //根据命盘等级，随机出盘位等级
//            int level = this.getDrawLevel();
//            //根据风水值，随机出品质
//            int quality = this.getDrawQuality();
//            //随机出对应的职业门客
//            List<WingRoomChakraPatronsAddItem> patronsAddList = this.randomPatronsList(occupation, type, quality, level);
//            if (patronsAddList == null || patronsAddList.size() <= 0) {
//                respMsg.setRet(GameErrorCode.E_CHAKRA_ATTRIBUTE_CONFIG_ERROR);
//                return respMsg;
//            }
//            //构建盘位数据
//            userWingRoomChakraDetail = new UserWingRoomChakraDetail();
//            userWingRoomChakraDetail.setUserId(player.getUserId());
//            userWingRoomChakraDetail.setOccupation(occupation);
//            userWingRoomChakraDetail.setType(type);
//            userWingRoomChakraDetail.setPosition(position);
//            userWingRoomChakraDetail.setWxType(wxType);
//            userWingRoomChakraDetail.setLevel(level);
//            userWingRoomChakraDetail.setQuality(quality);
//            userWingRoomChakraDetail.setPatronsList(patronsAddList);
//        }
//
//        //卜卦的盘位数据，存起来，确认后再真正装备。
//        this.userWingRoomChakra.setWaitChakraDetail(userWingRoomChakraDetail);
//
//        //增加抽取次数
//        this.addDrawNum();
//
//        //返回PB
//        respMsg.setRet(0);
//        respMsg.setChakraExp(this.userWingRoomChakra.getChakraExp());
//        respMsg.setChakraLevel(this.userWingRoomChakra.getChakraLevel());
//        respMsg.setChakraItem(WingRoomChakraPb.builderChakraItem(userWingRoomChakraDetail));
//        respMsg.setDrawNum(this.userWingRoomChakra.getDrawNum());
//        return respMsg;
//    }

    /**
     * 卜卦
     * @param reqMsg
     * @return
     */
    public synchronized WingRoomChakraProto.WingRoomChakraDrawRespMsg.Builder draw(WingRoomChakraProto.WingRoomChakraDrawReqMsg reqMsg) {
        WingRoomChakraProto.WingRoomChakraDrawRespMsg.Builder respMsg = WingRoomChakraProto.WingRoomChakraDrawRespMsg.newBuilder();
        int occupation = reqMsg.getOccupation();

        //抽取次数
        int drawNum = reqMsg.hasNum()? reqMsg.getNum() : 1;
        if (drawNum <= 0) {
            drawNum = 1;
        }

        //检测
        int ret = this.checkDraw(occupation, drawNum);
        if (ret > 0) {
            respMsg.setRet(ret);
            return respMsg;
        }

        //判断【四象，命格】是否还未装备,如果有直接返回
        List<UserWingRoomChakraDetail> waitChakraDetailList = this.userWingRoomChakra.getWaitChakraDetail();
        if (waitChakraDetailList != null && !waitChakraDetailList.isEmpty()) {
            //返回PB
            respMsg.setRet(0);
            respMsg.setChakraExp(this.userWingRoomChakra.getChakraExp());
            respMsg.setChakraLevel(this.userWingRoomChakra.getChakraLevel());
            for (UserWingRoomChakraDetail item : waitChakraDetailList) {
                WingRoomChakraProto.WingRoomChakraItem.Builder itemBuild = WingRoomChakraPb.builderChakraItem(item);
                respMsg.addChakraItemList(itemBuild);
            }
            return respMsg;
        }

        //命盘等级配置
        WingRoomChakraChartConfig chakraChartConfig = WingRoomConfigMgr.getWingRoomChakraChartConfig(this.userWingRoomChakra.getChakraLevel());

        //消耗道具
        Property cost = new Property();
        int costNum = drawNum * chakraChartConfig.getConsume();
        cost.setGood(GameConfig.CHAKRAS_WIND_WATER_PROP_ID, BigInteger.valueOf(costNum));
        boolean costResult = player.getModule(CurrencyModule.class).removeCurrency(cost, eLogMoneyType.WingRoomChakra, eLogMoneyType.WingRoomChakraDrawCost);
        if (!costResult) {
            //触发现金礼包
            player.notifyListener(eGamePlayerEventType.RechargeWingRoomChakra.getValue(), 0);
            respMsg.setRet(GameErrorCode.E_CHAKRA_DRAW_PROP_NOT_ENOUGH);
            return respMsg;
        }

        //抽取
        for (int i = 0; i < drawNum; i++) {
            //抽取一次
            UserWingRoomChakraDetail userWingRoomChakraDetail = this.drawOne(occupation);
            //卜卦的盘位数据，存起来，确认后再真正装备。
            this.userWingRoomChakra.addWaitChakraDetail(userWingRoomChakraDetail);
            respMsg.addChakraItemList(WingRoomChakraPb.builderChakraItem(userWingRoomChakraDetail));
        }

        //返回PB
        respMsg.setRet(0);
        respMsg.setChakraExp(this.userWingRoomChakra.getChakraExp());
        respMsg.setChakraLevel(this.userWingRoomChakra.getChakraLevel());
        respMsg.setDrawNum(this.userWingRoomChakra.getDrawNum());
        return respMsg;
    }

    /**
     * 抽取一次
     * @param occupation
     * @return
     */
    private UserWingRoomChakraDetail drawOne(int occupation) {
        //获取引导必中。没有引导必中走正常抽取
        UserWingRoomChakraDetail userWingRoomChakraDetail = this.getGuideDrawResult(occupation);
        if (userWingRoomChakraDetail == null) {
            //根据配置，随机出四象或者命格。随机出哪个盘位
            int position = this.getDrawPosition();
            //获取类型（四象或者命格）
            int type = this.getDrawType(occupation, position);
            //根据配置，随机出五行类型
            int wxType = this.getDrawWxType(type);
            //根据命盘等级，随机出盘位等级
            int level = this.getDrawLevel();
            //根据风水值，随机出品质
            int quality = this.getDrawQuality();
            //随机出对应的职业门客
            List<WingRoomChakraPatronsAddItem> patronsAddList = this.randomPatronsList(occupation, type, quality, level);
            //构建盘位数据
            userWingRoomChakraDetail = new UserWingRoomChakraDetail();
            userWingRoomChakraDetail.setUserId(player.getUserId());
            userWingRoomChakraDetail.setOccupation(occupation);
            userWingRoomChakraDetail.setType(type);
            userWingRoomChakraDetail.setPosition(position);
            userWingRoomChakraDetail.setWxType(wxType);
            userWingRoomChakraDetail.setLevel(level);
            userWingRoomChakraDetail.setQuality(quality);
            userWingRoomChakraDetail.setPatronsList(patronsAddList);
        }
        //增加抽取次数
        this.addDrawNum();
        //返回抽取到的装备
        return userWingRoomChakraDetail;
    }

    /**
     * 随机出加成门客
     * @param occupation 命盘序号
     * @param type 类型
     * @param quality 品质
     * @param level 等级
     * @return
     */
    private List<WingRoomChakraPatronsAddItem> randomPatronsList(int occupation, int type, int quality, int level) {
        List<UserPatrons> patronsList = player.getModule(PatronsModule.class).getUserPatronsList();
        //获取赚钱前N的门客
        patronsList.sort(Comparator.comparing(UserPatrons::getAbility).reversed());
        patronsList = patronsList.subList(0, this.getDrawPatronsPools(occupation));
        //属性配置
        WingRoomChakraAttributeConfig attributeConfig = WingRoomConfigMgr.getWingRoomChakraAttributeConfig(quality, level);
        if (attributeConfig == null) {
            return null;
        }
        //随机出N个门客
        int patronsNum = WingRoomConfigMgr.getDrawPatronsNum(this.getTotalWindWater());
        patronsList = RandomHelper.getRandomList(patronsList, patronsNum);
        //获取加成值
        return this.buildWingRoomChakraPatronsAddItemList(patronsList, type, attributeConfig);
    }

    /**
     * 获取门客加成ITEMlIST
     * @param patronsList
     * @param type
     * @param attributeConfig
     * @return
     */
    private List<WingRoomChakraPatronsAddItem> buildWingRoomChakraPatronsAddItemList(List<UserPatrons> patronsList, int type, WingRoomChakraAttributeConfig attributeConfig) {
        //获取加成值
        List<WingRoomChakraPatronsAddItem> list = new ArrayList<>();
        for (UserPatrons userPatrons : patronsList) {
            //加成值
            List<Integer> attributeList = attributeConfig.getEntryAttribute();
            if (type == WingRoomPositionTypeEnum.POSITION_TYPE_SX.getType()) {
                attributeList = attributeConfig.getIncrease();
            }
            int addValue = randomHelper.next(attributeList.get(0), attributeList.get(1) + 1);
            //构建
            WingRoomChakraPatronsAddItem patronsAddItem = new WingRoomChakraPatronsAddItem();
            patronsAddItem.setPatronsId(userPatrons.getPatronsId());
            patronsAddItem.setType(type);
            patronsAddItem.setAddValue(addValue);
            list.add(patronsAddItem);
        }
        return list;
    }

    /**
     * 装备
     * @param reqMsg
     * @return
     */
    public synchronized WingRoomChakraProto.WingRoomChakraInstallRespMsg.Builder install(WingRoomChakraProto.WingRoomChakraInstallReqMsg reqMsg) {
        WingRoomChakraProto.WingRoomChakraInstallRespMsg.Builder respMsg = WingRoomChakraProto.WingRoomChakraInstallRespMsg.newBuilder();
        //判断装备是否存在
        if (this.userWingRoomChakra.getWaitChakraDetail().isEmpty()) {
            respMsg.setRet(GameErrorCode.E_CHAKRA_INSTALL_CHAKRA_DETAIL_NOT_EXIST);
            return respMsg;
        }
        //默认处理第一个装备
        UserWingRoomChakraDetail chakraDetail = this.userWingRoomChakra.getWaitChakraDetail().get(0);

        //命盘等级配置
        WingRoomChakraChartConfig chakraChartConfig = WingRoomConfigMgr.getWingRoomChakraChartConfig(this.userWingRoomChakra.getChakraLevel());

        //原位置上的装备
        Map<Integer, Map<Integer, UserWingRoomChakraDetail>> positionTypeMap = this.userWingRoomChakraDetailMap.computeIfAbsent(chakraDetail.getOccupation(), k -> new HashMap<>());
        Map<Integer, UserWingRoomChakraDetail> positionMap = positionTypeMap.computeIfAbsent(chakraDetail.getType(), k -> new HashMap<>());
        UserWingRoomChakraDetail oldChakraDetail = positionMap.get(chakraDetail.getPosition());

        //判断是否舍弃
        if (reqMsg.getType() == WingRoomInstallTypeEnum.INSTALL_TYPE_NOT.getType()) {
            if (reqMsg.getGiveUpIndexCount() > 0) {
                //全部舍弃
                this.giveUpMulByIndex(reqMsg.getGiveUpIndexList());
            } else {
                //舍弃单个
                this.giveUpOne(chakraDetail, oldChakraDetail);
            }
            //返回PB
            respMsg.setRet(0);
            respMsg.setChakraExp(this.userWingRoomChakra.getChakraExp());
            respMsg.setChakraLevel(this.userWingRoomChakra.getChakraLevel());
            for (UserWingRoomChakraDetail item : this.userWingRoomChakra.getWaitChakraDetail()) {
                respMsg.addWaitChakraItemList(WingRoomChakraPb.builderChakraItem(item));
            }
            return respMsg;
        }

        //日志结构
        LogWingRoomChakraDraw logWingRoomChakraDraw = this.createInstallLog(chakraDetail, oldChakraDetail, reqMsg.getType());

        //装备
        if (oldChakraDetail == null) {
            chakraDetail.setCreateTime(System.currentTimeMillis());
            chakraDetail.setInsertOption();
        } else {
            chakraDetail.setCreateTime(oldChakraDetail.getCreateTime());
            chakraDetail.setUpdateTime(System.currentTimeMillis());
            chakraDetail.setUpdateOption();
        }
        positionMap.put(chakraDetail.getPosition(), chakraDetail);

        //清除待装备
        this.userWingRoomChakra.removeWaitChakraDetailFirst();
        if (oldChakraDetail != null) {
            if (reqMsg.getGiveUpReplace()) {
                //增加命盘经验
                this.addExp(chakraChartConfig.getConsume());
            } else {
                //存在旧装备且不自动替换返回待装备
                this.userWingRoomChakra.addWaitChakraDetailFirst(oldChakraDetail);
            }
        }

        //计算各个门客加了多少赚钱
        for (WingRoomChakraPatronsAddItem patronsAddItem : chakraDetail.getPatronsList()) {
            BigDecimal addAbility = BigDecimal.ZERO;
            if (patronsAddItem.getType() == WingRoomPositionTypeEnum.POSITION_TYPE_MG.getType()) {
                addAbility = player.getModule(PatronsModule.class).qualificationAddAbility(patronsAddItem.getPatronsId(), (int) patronsAddItem.getAddValue());
            } else if (patronsAddItem.getType() == WingRoomPositionTypeEnum.POSITION_TYPE_SX.getType()) {
                addAbility = player.getModule(PatronsModule.class).rateAddAbility(patronsAddItem.getPatronsId(), (int) patronsAddItem.getAddValue());
            }
            patronsAddItem.setAddAbility(addAbility.longValue());
            chakraDetail.setUpdateOption();
        }

        //门客属性变换处理
        this.patronsChangeHandle(oldChakraDetail, chakraDetail);

        //日志
        AutoLogMgr.add(logWingRoomChakraDraw);

        //返回PB
        respMsg.setRet(0);
        respMsg.addAllWingRoomChakraItem(WingRoomChakraPb.buildChakraDetailList(this.userWingRoomChakraDetailMap));
        respMsg.setChakraExp(this.userWingRoomChakra.getChakraExp());
        respMsg.setChakraLevel(this.userWingRoomChakra.getChakraLevel());
        for (UserWingRoomChakraDetail item : this.userWingRoomChakra.getWaitChakraDetail()) {
            respMsg.addWaitChakraItemList(WingRoomChakraPb.builderChakraItem(item));
        }
        return respMsg;
    }

    /**
     * 舍弃一个
     * @param chakraDetail
     * @param oldChakraDetail
     */
    private void giveUpOne(UserWingRoomChakraDetail chakraDetail, UserWingRoomChakraDetail oldChakraDetail) {
        WingRoomChakraChartConfig chakraChartConfig = WingRoomConfigMgr.getWingRoomChakraChartConfig(this.userWingRoomChakra.getChakraLevel());
        //增加命盘经验
        this.addExp(chakraChartConfig.getConsume());
        //舍弃
        this.userWingRoomChakra.removeWaitChakraDetailFirst();
        //日志
        LogWingRoomChakraDraw logWingRoomChakraDraw = this.createInstallLog(chakraDetail, oldChakraDetail, WingRoomInstallTypeEnum.INSTALL_TYPE_NOT.getType());
        AutoLogMgr.add(logWingRoomChakraDraw);
    }

    /**
     * 舍弃多个，根据下标
     * @param delIndexList
     */
    private void giveUpMulByIndex(List<Integer> delIndexList) {
        WingRoomChakraChartConfig chakraChartConfig = WingRoomConfigMgr.getWingRoomChakraChartConfig(this.userWingRoomChakra.getChakraLevel());
        //保留的装备LIST
        List<UserWingRoomChakraDetail> saveList = new ArrayList<>();
        //要删除的装备LIST
        List<UserWingRoomChakraDetail> delList = new ArrayList<>();
        //遍历待装备LIST
        for (int i = 0; i < this.userWingRoomChakra.getWaitChakraDetail().size(); i++) {
            UserWingRoomChakraDetail chakraDetail = this.userWingRoomChakra.getWaitChakraDetail().get(i);
            //判断是否是要删除的元素
            if (delIndexList.contains(i)) {
                delList.add(chakraDetail);
            } else {
                saveList.add(chakraDetail);
            }
        }
        //保存saveList
        this.userWingRoomChakra.setWaitChakraDetail(saveList);
        //舍弃处理
        for (UserWingRoomChakraDetail chakraDetail : delList) {
            //查看位置上的旧命盘
            UserWingRoomChakraDetail oldChakraDetail = this.getChakraDetail(chakraDetail.getOccupation(), chakraDetail.getType(), chakraDetail.getPosition());
            //增加命盘经验
            this.addExp(chakraChartConfig.getConsume());
            //日志
            LogWingRoomChakraDraw logWingRoomChakraDraw = this.createInstallLog(chakraDetail, oldChakraDetail, WingRoomInstallTypeEnum.INSTALL_TYPE_NOT.getType());
            AutoLogMgr.add(logWingRoomChakraDraw);
        }
    }

    /**
     * 构建装备操作日志
     * @param chakraDetail
     * @param oldChakraDetail
     * @param handleType
     * @return
     */
    private LogWingRoomChakraDraw createInstallLog(UserWingRoomChakraDetail chakraDetail, UserWingRoomChakraDetail oldChakraDetail, int handleType) {
        //日志结构
        LogWingRoomChakraDraw logWingRoomChakraDraw = new LogWingRoomChakraDraw();
        logWingRoomChakraDraw.setUserId(player.getUserId());
        logWingRoomChakraDraw.setOccupation(chakraDetail.getOccupation());
        logWingRoomChakraDraw.setLevel(this.userWingRoomChakra.getChakraLevel());
        logWingRoomChakraDraw.setType(chakraDetail.getType());
        logWingRoomChakraDraw.setPosition(chakraDetail.getPosition());
        if (handleType == WingRoomInstallTypeEnum.INSTALL_TYPE_DO.getType() && oldChakraDetail != null) {
            handleType = WingRoomInstallTypeEnum.INSTALL_TYPE_REPLACE.getType();
        }
        logWingRoomChakraDraw.setHandleType(handleType);
        logWingRoomChakraDraw.setDetail(chakraDetail);
        logWingRoomChakraDraw.setOldDetail(oldChakraDetail);
        return logWingRoomChakraDraw;
    }

    /**
     * 门客属性变化处理
     * @param oldChakraDetail
     * @param chakraDetail
     */
    private void patronsChangeHandle(UserWingRoomChakraDetail oldChakraDetail, UserWingRoomChakraDetail chakraDetail) {
        //门客属性变化
        List<UserPatrons> changePatronsList = new ArrayList<>();
        if (oldChakraDetail != null) {
            for (WingRoomChakraPatronsAddItem patronsAddItem : oldChakraDetail.getPatronsList()) {
                UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(patronsAddItem.getPatronsId());
                changePatronsList.add(userPatrons);
            }
        }
        for (WingRoomChakraPatronsAddItem patronsAddItem : chakraDetail.getPatronsList()) {
            UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(patronsAddItem.getPatronsId());
            changePatronsList.add(userPatrons);
        }
        player.getModule(PatronsModule.class).onPatronsChangeByList(changePatronsList);
    }

    /**
     * 获取被拜访记录LIST
     * @return
     */
    public WingRoomChakraProto.WingRoomChakraGetBeVisitListRespMsg.Builder getBeVisitList() {
        WingRoomChakraProto.WingRoomChakraGetBeVisitListRespMsg.Builder respMsg = WingRoomChakraProto.WingRoomChakraGetBeVisitListRespMsg.newBuilder();
        respMsg.setRet(0);
        for (UserWingRoomChakraBeVisitRecord beVisitRecord : this.userBeVisitRecordList) {
            PlayerProto.PlayerBaseTempMsg.Builder pbPlayer = PlayerBasePb.parsePlayerBaseTempMsg(beVisitRecord.getVisitUserInfo());
            WingRoomChakraProto.VisitPlayerBaseItem.Builder visitPlayer = WingRoomChakraProto.VisitPlayerBaseItem.newBuilder();
            visitPlayer.setUserId(beVisitRecord.getVisitUserId());
            visitPlayer.setVisitPlayerBaseData(pbPlayer);
            visitPlayer.setVisitTime(beVisitRecord.getCreateTime());
            respMsg.addVisitPlayerBaseData(visitPlayer);
        }
        return respMsg;
    }
}
